﻿spa = spa || {};

spa.sortdirection = {
    ascending: "asc",
    descending: "desc",
};

spa.pager = function (pageSize, orderBy, direction, onFilterChange) {
    /// <summary>
    /// This will create an o-data compatible pager
    /// set defaults for pageSize, orderBy, and direction (asc or desc)
    /// onPageChange = a function to execute when the page changes
    /// </summary>
    var pager = this;
    var onFilterChange = onFilterChange;

    // Properties
    pager.Total = ko.observable(0);
    /// <summary>
    /// Get or Set the Total number of elements in the resultset
    /// </summary>
    pager.PageSize = ko.observable(pageSize);
    pager.OnPage = ko.observable(1);
    pager.OrderBy = ko.observable(orderBy);
    pager.Direction = ko.observable(direction);

    pager.ChangeSort = function (column) {
        /// <summary>
        /// This will change the ordering of data
        /// using a natural methodology for a table display
        /// </summary>
        if (pager.OrderBy() == column) {
            if (pager.Direction() == "asc") {
                pager.Direction("desc");
            }
            else {
                pager.Direction("asc");
            }
        }
        pager.OrderBy(column);
    };

    // Computed Properties
    pager.Pages = ko.computed(function () {
        /// <summary>
        /// Returns an array of integers representing the available pages
        /// this is a 1-based array, such as 1,2,3,4
        /// </summary>
        var pages = [];
        var lastPage = Math.ceil(pager.Total() / pager.PageSize());
        for (var p = 1; p <= lastPage; p++) {
            pages.push(p);
        }
        return pages;
    });

    pager.CanMoveNextPage = ko.computed(function () {
        /// <summary>
        /// Returns true/false if there is another page to move to
        /// </summary>
        var lastPage = Math.ceil(pager.Total() / pager.PageSize());
        return (pager.OnPage() < lastPage);
    });

    pager.MoveNextPage = ko.computed(function () {
        /// <summary>
        /// Advances to the next page (if possible)
        /// </summary>
        var lastPage = Math.ceil(pager.Total() / pager.PageSize());
        if (pager.OnPage() < lastPage)
            pager.OnPage(pager.OnPage() + 1);
    });

    pager.CanMovePrevPage = ko.computed(function () {
        /// <summary>
        /// Returns true/false if we can go to an earlier page
        /// </summary>
        return (pager.OnPage() > 1);
    });

    pager.MovePrevPage = ko.computed(function () {
        /// <summary>
        /// Advances to the next page (if possible)
        /// </summary>
        if (pager.OnPage() > 1)
            pager.OnPage(pager.OnPage() - 1);
    });

    pager.Filter = ko.computed(function () {
        /// <summary>
        /// Returns the part of the $filter condition controlled by paging. 
        /// This includes $skip, $top, and $orderby
        /// </summary>
        var skip = (pager.OnPage() - 1) * pager.PageSize();
        return "$skip=" + skip + "&$top=" + pager.PageSize() + "&$orderby=" + pager.OrderBy() + "+" + pager.Direction();
    });

    // Internal Subscriptions (this provides the automatic Interactivity)
    pager.Total.subscribe(function (newtotal) {
        pager.OnPage(1);
    });
    pager.PageSize.subscribe(function (newtotal) {
        pager.OnPage(1);
    });
    pager.Filter.subscribe(onFilterChange);

    return pager;
};